package com.quanxiaoha.weblog.admin.utils;

import com.quanxiaoha.weblog.admin.config.MinioProperties;
import com.quanxiaoha.weblog.admin.model.vo.image.QueryImageListRspVO;
import io.minio.*;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author: 犬小哈
 * @url: www.quanxiaoha.com
 * @date: 2023-05-11 9:02
 * @description: TODO
 **/
@Component
@Slf4j
public class MinioUtil {

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private MinioClient minioClient;

    public String uploadFile(MultipartFile file, String prefix, boolean saveFilename) throws Exception {
        if (file == null || file.getSize() == 0) {
            log.error("==> 上传文件异常：文件大小为空 ...");
            throw new RuntimeException("文件大小不能为空");
        }

        String originalFileName = file.getOriginalFilename();
        String contentType = file.getContentType();
        String objectName;
        if (saveFilename) {
            objectName = String.format("%s/%s", prefix, originalFileName);
            if (fileExists(objectName)) {
                return String.format("/%s/%s", minioProperties.getBucketName(), objectName);
            }
        } else {
            String key = UUID.randomUUID().toString().replace("-", "");
            String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
            objectName = String.format("%s/%s%s", prefix, key, suffix);
        }
        log.info("==> 开始上传文件至 Minio, ObjectName: {}", objectName);
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioProperties.getBucketName())
                .object(objectName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(contentType)
                .build());

        String url = String.format("/%s/%s", minioProperties.getBucketName(), objectName);
        log.info("==> 上传文件至 Minio 成功，访问路径: {}", url);
        return url;
    }

    public boolean fileExists(String objectName) {
        StatObjectArgs args = StatObjectArgs.builder()
                .bucket(minioProperties.getBucketName())
                .object(objectName)
                .build();
        try {
            StatObjectResponse statObjectResponse = minioClient.statObject(args);
            if (!statObjectResponse.deleteMarker()) {
                // 如果对象存在则不上传
                return true;
            }
        } catch (Exception ignored) {

        }
        return false;
    }

    public List<QueryImageListRspVO> getAllFile(String prefix) {
        ListObjectsArgs args = ListObjectsArgs.builder()
                .bucket(minioProperties.getBucketName())
                .prefix(prefix + "/")
                .build();
        Iterable<Result<Item>> results = minioClient.listObjects(args);
        List<QueryImageListRspVO> list = new ArrayList<>();
        results.forEach(item -> {
            QueryImageListRspVO vo = new QueryImageListRspVO();
            try {
                vo.setSrc("/" + minioProperties.getBucketName() + "/" + item.get().objectName());
                vo.setSize(item.get().size());
            } catch (Exception e) {
                return;
            }
            list.add(vo);
        });
        return list;
    }

    public void deleteFile(String name) {
        RemoveObjectArgs args = RemoveObjectArgs.builder()
                .bucket(minioProperties.getBucketName())
                .object(name)
                .build();
        try {
            minioClient.removeObject(args);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
